package com.youxuit.youxu.kecheng.CASandAtomic;

import lombok.SneakyThrows;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;

public class LongAdderTest {
    public static void main(String[] args) {
        testAtomicLongVSLongAdder(10, 10000);
        System.out.println("==================");
        testAtomicLongVSLongAdder(10, 200000);
        System.out.println("==================");
        testAtomicLongVSLongAdder(100, 200000);
    }

     static  void  testAtomicLongVSLongAdder(final int threadCount , final int times){
         long start = System.currentTimeMillis();
         testLongAddr(threadCount,times);
         long end = System.currentTimeMillis()- start;
         System.out.println("条件>>>>>>线程数:" + threadCount + ", 单线程操作计数" + times);
         System.out.println("结果>>>>>>LongAdder方式增加计数" + (threadCount * times) + "次,共计耗时:" + end);

         long start1 = System.currentTimeMillis();
         testLongAddr(threadCount,times);
         long end1 = System.currentTimeMillis()- start1;
         System.out.println("条件>>>>>>线程数:" + threadCount + ", 单线程操作计数" + times);
         System.out.println("结果>>>>>>AtomicLong方式增加计数" + (threadCount * times) + "次,共计耗时:" + end1);
     }

     @SneakyThrows
     static void testAtomicLong(final int threadCount , final int times){
         CountDownLatch countDownLatch = new CountDownLatch(threadCount);
         AtomicLong atomicLong = new AtomicLong();
         for (int i = 0; i < threadCount; i++) {
             new Thread(new Runnable() {
                 @Override
                 public void run() {
                     for (int j = 0; j < times; j++) {
                         atomicLong.incrementAndGet();
                     }
                     countDownLatch.countDown();
                 }

             },"my_thread"+i).start();
         }
         countDownLatch.await();
     }
     @SneakyThrows
     static void testLongAddr(final int threadCount , final int times){
         CountDownLatch countDownLatch = new CountDownLatch(threadCount);
         LongAdder longAdder = new LongAdder();
         for (int i = 0; i < threadCount; i++) {
             new Thread(new Runnable() {
                 @Override
                 public void run() {
                     for (int j = 0; j < times; j++) {
                         longAdder.add(1);
                     }
                     countDownLatch.countDown();
                 }
             },"my_thread"+i).start();
         }
         countDownLatch.await();
     }
}
